<?php

class TruyentranhController extends Zend_Controller_Action {

    const KEY_CACHED = "truyentranh_cached";

    private static $memcache;

    public function __construct(Zend_Controller_Request_Abstract $request, Zend_Controller_Response_Abstract $response, array $invokeArgs = array()) {
        parent::__construct($request, $response, $invokeArgs);

        if (Haibl_ConfigData::SUPPORT_MEMCACHED) {
            self::$memcache = new Memcache;
            self::$memcache->connect(Haibl_ConfigData::DOMAIN, Haibl_ConfigData::PORT) or die("Could not connect");
        }
    }

    //http://localhost/public/truyentranh/category -> get Id needed
    //http://localhost/public/truyentranh/detailcategory?id=4&page=1&count=100
    //Lay duoc danh sach truyen -> get href needed
    //http://localhost/public/truyentranh/getcommicinfo?href=http://vuitruyentranh.vn/truyen-tranh/doraemon---doremon/583/
    //get commic info, page url
    //Trong app se co 2 nut
    //Xem - Download het    
    //[
    //"http://vuitruyentranh.vn/truyen-tranh/doraemon---doremon/583/page/1",
    //"http://vuitruyentranh.vn/truyen-tranh/doraemon---doremon/583/page/2",
    //"http://vuitruyentranh.vn/truyen-tranh/doraemon---doremon/583/page/3"
    //]
    //http://localhost/public/truyentranh/getcommic?href=http://vuitruyentranh.vn/truyen-tranh/doraemon---doremon/583/page/3
    //get danh sach cac tap truyen cua truyen tranh href -> get readUrl needed
    //http://localhost/public/truyentranh/getimagecommic?href=http://vuitruyentranh.vn/truyen-tranh/doraemon---doremon/tap-23/583/146/2/
    //get het hinh ve

    public function checkAccessKeyParams() {
        return true;
        $appid = $this->_request->getParam("key");
        $sig = $this->_request->getParam("sig");
        $ts = $this->_request->getParam("ts");
        $db = $this->_request->getParam("db");
        if ($db == '1')
            return true;

        $time = time();
        //60s * 15; 
        if($time - $ts > 60 * 15 || $time - $ts < 0){
            echo Sunny_ErrorHandled::handleError(Sunny_ErrorHandled::$NO_DATA_RECORD);
            return;
        }

        if ($appid == "" || $sig == "" || $ts == "") {
            echo Sunny_ErrorHandled::handleError(Sunny_ErrorHandled::$INVAILD_PARAMS);
            return false;
        } else {
            if ($appid != Haibl_ConfigData::KEY
                            && $appid != 963852) {
                echo Sunny_ErrorHandled::handleError(Sunny_ErrorHandled::$NOT_FOUND_APIKEY);
                return false;
            } else {
                $params = $this->_request->getParams();
                $requestParams = '';
                foreach ($params as $key => $value) {
                    if ($key != 'controller' && $key != 'action' && $key != 'module' && $key != "sig") {
                        $requestParams.= $key . '=' . $value;
                    }
                }
                $requestParams.= Haibl_ConfigData::ACCESS_KEY;
                $encryptParams = md5($requestParams);

                if ($encryptParams == $sig) {
                    return true;
                } else {
                    echo Sunny_ErrorHandled::handleError(Sunny_ErrorHandled::$NOT_FOUND_APIKEY);
                    if (Haibl_ConfigData::DEBUG) {
                        echo "<p>encryptParams = " . $encryptParams . "</p>";
                    }
                    return false;
                }
            }
        }
    }

    public function categoryAction() {
        $this->_helper->viewRenderer->setNoRender(true);
        if (!$this->checkAccessKeyParams())
            return;
        $base = 'http://' . $_SERVER['SERVER_NAME'] . $this->_request->getBaseUrl() . '/images/khoanh/';
        $CATE = array(
            array("name" => "Truyện Hành Động",
                "id" => "1",
                "image" => $base . 'hanhdong.png'),
            array("name" => "Truyện Tình Cảm",
                "id" => "2",
                "image" => $base . 'tinhcam.png'),
            array("name" => "Truyện Trinh Thám",
                "id" => "3",
                "image" => $base . 'trinhtham.png'),
            array("name" => "Truyện Viễn Tưởng",
                "id" => "4",
                "image" => $base . 'vientuong.png'),
            array("name" => "Truyện Thể Thao",
                "id" => "6",
                "image" => $base . 'thethao.png'),
            array("name" => "Truyện Học Đường",
                "id" => "7",
                "image" => $base . 'hocduong.png'),
            array("name" => "Truyện Kinh Dị",
                "id" => "8",
                "image" => $base . 'kinhdi.png'),
            array("name" => "Truyện Hài Hước",
                "id" => "11",
                "image" => $base . 'haihuoc.png'),
            array("name" => "Truyện Đặc Sắc",
                "id" => "12",
                "image" => $base . 'dacsac.png'),
            array("name" => "Xì tin Manga",
                "id" => "13",
                "image" => $base . 'xitin.png')
        );

        $returnData['errorId'] = Sunny_ErrorHandled::$DONE;
        $returnData['data'] = $CATE;        
        
        $private_url = "http://vuitruyentranh.vn/";
        $client = new Zend_Http_Client($private_url);
        $response = $client->request(Zend_Http_Client::GET);
        $html = $response->getBody();
        
        $dom = new Zend_Dom_Query($html);
        $results = $dom->query('.jcarousel-skin-tango');

        $results->rewind();
        $domDoc = $results->current();
        
        $li = $domDoc->getElementsByTagName('li');
        if(!empty($li)){
            $length = $li->length;
            $list = array();
            for($iter = 0 ; $iter < $length ; $iter++){
                $li_item = $li->item($iter);
                
                $list[$iter]['href'] = $li_item->getElementsByTagName('a')->item(0)->getAttribute('href');
                $list[$iter]['src'] =$li_item->getElementsByTagName('img')->item(0)->getAttribute('src');
                $list[$iter]['title'] =$li_item->getElementsByTagName('img')->item(0)->getAttribute('alt');
                $list[$iter]['title'] = $list[$iter]['title'];
            }
            
            $returnData['hot'] = $list;
        }

        echo json_encode($returnData);
    }

    public function detailcategoryAction() {
        $this->_helper->viewRenderer->setNoRender(true);
        $CATE = array(
            array("name" => "Truyện Hành Động",
                "id" => "1",
                "url" => "http://vuitruyentranh.vn/truyen-tranh-hanh-dong/1/"),
            array("name" => "Truyện Tình Cảm",
                "id" => "2",
                "url" => "http://vuitruyentranh.vn/truyen-tranh-tinh-cam/2/"),
            array("name" => "Truyện Trinh Thám",
                "id" => "3",
                "url" => "http://vuitruyentranh.vn/truyen-tranh-trinh-tham/3/"),
            array("name" => "Truyện Viễn Tưởng",
                "id" => "4",
                "url" => "http://vuitruyentranh.vn/truyen-tranh-vien-tuong/4/"),
            array("name" => "Truyện Thể Thao",
                "id" => "6",
                "url" => "http://vuitruyentranh.vn/truyen-tranh-the-thao/6/"),
            array("name" => "Truyện Học Đường",
                "id" => "7",
                "url" => "http://vuitruyentranh.vn/truyen-tranh-hoc-duong/7/"),
            array("name" => "Truyện Kinh Dị",
                "id" => "8",
                "url" => "http://vuitruyentranh.vn/truyen-tranh-kinh-di/8/"),
            array("name" => "Truyện Hài Hước",
                "id" => "11",
                "url" => "http://vuitruyentranh.vn/truyen-tranh-hai-huoc/11/"),
            array("name" => "Truyện Đặc Sắc",
                "id" => "12",
                "url" => "http://vuitruyentranh.vn/truyen-tranh-truyen-dac-sac/12/"),
            array("name" => "Xì tin Manga",
                "id" => "13",
                "url" => "http://vuitruyentranh.vn/truyen-tranh-xi-tin-manga/13/"),
        );

        $id = $this->_request->getParam("id");
        $page = $this->_request->getParam("page");
        $count = $this->_request->getParam("count");
        if (empty($page))
            $page = 1;
        if (empty($count))
            $count = 20;

        $category_current = null;
        if (!empty($id)) {
            foreach ($CATE as $key => $value) {
                $cate_id = $CATE[$key]['id'];
                if ($cate_id == $id) {
                    $category_current = $CATE[$key];
                }
            }
        }

        if (!empty($category_current)) {
            $category_current['url'] = $category_current['url'] . 'page/' . $page;
            $private_url = 'http://vuitruyentranh.vn/vmg/index/main?page=' . $page . '&status=&char=&cat=' . $id . '&type=&style=grid&author=&limit=' . $count;

            $client = new Zend_Http_Client($private_url);
            $client->setHeaders('Host', 'vuitruyentranh.vn');
            $client->setHeaders('X-Requested-With', 'XMLHttpRequest');
            $client->setHeaders('User-Agent', 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/27.0.1453.116 Safari/537.36');
            $client->setHeaders('Referer', $category_current['url']);
            $client->setHeaders('Accept-Encoding', 'gzip,deflate,sdch');
            $client->setHeaders('Accept-Language', 'vi,en-US;q=0.8,en;q=0.6');

            $response = $client->request(Zend_Http_Client::POST);
            $html = $response->getBody();
            $dom = new Zend_Dom_Query($html);
            $results = $dom->query('.truyen-tranh-block');

            $data = array();
            $dataIndex = 0;

            $results->rewind();
            while ($results->valid()) {
                $domDoc = $results->current();

                $a = $domDoc->getElementsByTagName('a');
                if (!empty($a)) {
                    $a = $a->item(0);
                    $data[$dataIndex]['href'] = $a->getAttribute("href");
                    $data[$dataIndex]['title'] = self::toLatin1(trim($a->getAttribute("title")));

                    $data[$dataIndex]['title'] = trim(str_replace("Truyện tranh", '', $data[$dataIndex]['title']));
                }

                $img = $domDoc->getElementsByTagName('img');
                if (!empty($img)) {
                    $img = $img->item(0);
                    $data[$dataIndex]['src'] = $img->getAttribute("src");
                }

                $dataIndex++;
                $results->next();
            }

            $returnData['errorId'] = Sunny_ErrorHandled::$DONE;
            $returnData['data'] = $data;
            echo json_encode($returnData);
        }
    }

    public function searchAction() {
        $this->_helper->viewRenderer->setNoRender(true);

        $search = $this->_request->getParam("search");
        $page = $this->_request->getParam("page");
        if (empty($page))
            $page = 1;
        if (!empty($search)) {
            
            $search = urlencode($search);
            $url = "http://vuitruyentranh.vn/tim-kiem?search=" . $search . "&page=" . $page;
            
            $client = new Zend_Http_Client($url);

            $client->setHeaders('Host', 'vuitruyentranh.vn');
            $client->setHeaders('Connection', 'keep-alive');
            $client->setHeaders('Accept', 'application/json, text/javascript, */*; q=0.01');
            $client->setHeaders('Origin', 'http://vuitruyentranh.vn');
            $client->setHeaders('X-Requested-With', 'XMLHttpRequest');
            $client->setHeaders('Content-Type', 'application/x-www-form-urlencoded');
            $client->setHeaders('Accept-Encoding', 'gzip,deflate,sdch');
            $client->setHeaders('Accept-Language', 'vi,en-US;q=0.8,en;q=0.6');
            $client->setHeaders('User-Agent', 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/27.0.1453.116 Safari/537.36');

            $response = $client->request(Zend_Http_Client::GET);
            $json = $response->getBody();
            
            $dom = new Zend_Dom_Query($json);
            $results = $dom->query('.update-table');
            $results->rewind();


            $data = array();

            while ($results->valid()) {
                $current = $results->current();

                $h2ResultCount = 0;//$current->getElementsByTagName('h2');
//                if (!empty($h2ResultCount)) {
//                    $h2ResultCount = $h2ResultCount->item(0);
//                    $resultsString = self::toLatin1($h2ResultCount->nodeValue);
//                    $resultsString = str_replace('Tìm thấy ', '', $resultsString);
//                    $resultsString = str_replace(' kết quả truyện tranh với từ khóa: “' . $search . '”', '', $resultsString);
                    $data['total'] = ''.$h2ResultCount;
//                }

                $childData = array();
                $li = $current->getElementsByTagName('li');
                if (!empty($li)) {
                    $length = $li->length;
                    for ($iter = 0; $iter < $length - 4; $iter++) {
                        $currentLi = $li->item($iter);

                        $a = $currentLi->getElementsByTagName('a')->item(0);
                        if($a->getAttribute('href') == '#') break;
                        $childData[$iter]['href'] = $a->getAttribute('href');
                        $childData[$iter]['title'] = $a->getAttribute('title');                        
                        $childData[$iter]['title'] = trim(str_replace('Đọc truyện tranh', '', $childData[$iter]['title']));

                        $img = $currentLi->getElementsByTagName('img')->item(0);
                        if(!empty($img)) {
                            $childData[$iter]['src'] = $img->getAttribute('src');
                        }
                                
                        
                    }
                }

                $data['result'] = $childData;
                break;
            }

            $returnData['errorId'] = Sunny_ErrorHandled::$DONE;
            $returnData['data'] = $data;
            echo json_encode($returnData);
        }
    }

    public function getcommicAction() {
        $this->_helper->viewRenderer->setNoRender(true);

        $href = $this->_request->getParam("href");
        if (!empty($href)) {
            $client = new Zend_Http_Client('http://vuitruyentranh.vn');
            $client->setUri('http://vuitruyentranh.vn/vmg/story/reverser-chapter');
            $client->setHeaders('Host', 'vuitruyentranh.vn');
            $client->setHeaders('Connection', 'keep-alive');
            $client->setHeaders('Accept', 'application/json, text/javascript, */*; q=0.01');
            $client->setHeaders('Origin', 'http://vuitruyentranh.vn');
            $client->setHeaders('X-Requested-With', 'XMLHttpRequest');
            $client->setHeaders('Content-Type', 'application/x-www-form-urlencoded');
            $client->setHeaders('Accept-Encoding', 'gzip,deflate,sdch');
            $client->setHeaders('Accept-Language', 'vi,en-US;q=0.8,en;q=0.6');
            $client->setHeaders('User-Agent', 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/27.0.1453.116 Safari/537.36');
            $client->setHeaders('Referer', $href);

            $post_data = explode("/", $href);
            $length = count($post_data);
            $page = $post_data[$length - 1];
            $id = $post_data[$length - 3];

            $client->setParameterPost("page", $page);
            $client->setParameterPost("order", "1");
            $client->setParameterPost("id", $id);

            $response = $client->request(Zend_Http_Client::POST);
            $json = $response->getBody();
            echo $json;
        }
    }

    function startsWith($haystack, $needle) {
        return !strncmp($haystack, $needle, strlen($needle));
    }

    public function getimagecommicAction() {
        $this->_helper->viewRenderer->setNoRender(true);

        $href = $this->_request->getParam("href");
        if (!empty($href)) {
            $client = new Zend_Http_Client($href);
            $client->setHeaders('Host', 'vuitruyentranh.vn');
            $client->setHeaders('X-Requested-With', 'XMLHttpRequest');
            $client->setHeaders('User-Agent', 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/27.0.1453.116 Safari/537.36');
            $client->setHeaders('Referer', $href);
            $client->setHeaders('Accept-Encoding', 'gzip,deflate,sdch');
            $client->setHeaders('Accept-Language', 'vi,en-US;q=0.8,en;q=0.6');

            $response = $client->request(Zend_Http_Client::POST);
            $html = $response->getBody();
            $dom = new Zend_Dom_Query($html);
            $results = $dom->query('.main-content');
            $results->rewind();
            $domDoc = $results->current();

            $script = $domDoc->getElementsByTagName('script');
            $value = $script->item(0)->nodeValue;

            $value = explode("var", $value);
            $length = count($value);

            $imageList = null;
            $imageUrl = '';
            for ($iter = 0; $iter < $length; $iter++) {
                $line = trim($value[$iter]);

                if (!empty($line)) {
                    if ($this->startsWith($line, 'textPageList')) {
                        $line = str_replace('textPageList = \'', '', $line);
                        $line = str_replace('\';', '', $line);
                        $line = str_replace('\"', '"', $line);
                        $line = str_replace('\'', '"', $line);

                        $imageList = json_decode($line);
                    } else if ($this->startsWith($line, 'imageUrl')) {
                        $line = str_replace('imageUrl = \'', '', $line);
                        $line = str_replace('\';', '', $line);

                        $imageUrl = $line;
                    }
                }
            }

            $returnData['errorId'] = Sunny_ErrorHandled::$DONE;
            $returnData['imageUrl'] = $imageUrl;
            $returnData['imageList'] = $imageList;
            echo json_encode($returnData);
        }
    }

    public function getcommicinfoAction() {
        $this->_helper->viewRenderer->setNoRender(true);

        $href = $this->_request->getParam("href");
        if (!empty($href)) {
            $client = new Zend_Http_Client($href);
            $client->setHeaders('Host', 'vuitruyentranh.vn');
            $client->setHeaders('X-Requested-With', 'XMLHttpRequest');
            $client->setHeaders('User-Agent', 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/27.0.1453.116 Safari/537.36');
            $client->setHeaders('Referer', $href);
            $client->setHeaders('Accept-Encoding', 'gzip,deflate,sdch');
            $client->setHeaders('Accept-Language', 'vi,en-US;q=0.8,en;q=0.6');

            $response = $client->request(Zend_Http_Client::POST);
            $html = $response->getBody();

            $dom = new Zend_Dom_Query($html);
            $results = $dom->query('.description');

            $results->rewind();
            $domDoc = $results->current();

            $p = $domDoc->getElementsByTagName('p');
            $des = "";
            if (!empty($p)) {
                $span = $p->item(1)->getElementsByTagName('span');
                for ($iter = 0; $iter < $span->length; $iter++) {
                    $child = $span->item($iter);
                    $des .= $child->nodeValue;
                }
                $des = html_entity_decode($des, ENT_QUOTES, 'utf-8');
            }

            $results = $dom->query('.PageList');

            $results->rewind();

            $page_max = 1;
            while ($results->valid()) {
                $domDoc = $results->current();

                $a = $domDoc->getElementsByTagName('a');
                if (!empty($a)) {
                    $onClick = $a->item(0)->getAttribute('onclick');
                    if (strpos($onClick, 'loadMoreChapter') !== false) {
                        
                        $li = $domDoc->getElementsByTagName('li');
                        if (!empty($li)) {
                            $li = $li->item($li->length - 1);
                            if (!empty($li)) {
                                $page_max = trim($li->nodeValue);
                            }
                        }
                    }
                } break;
            }

            $page = null;
            for ($i = 1; $i <= $page_max; $i++) {
                $page[] = $href . 'page/' . $i;
            }

            $data = array();
            $data['desc'] = self::fixUTF8($des);
            $data['page'] = $page;

            $returnData['errorId'] = Sunny_ErrorHandled::$DONE;
            $returnData['data'] = $data;
            echo json_encode($returnData);
        }
    }

    protected static $win1252ToUtf8 = array(
        128 => "\xe2\x82\xac",
        130 => "\xe2\x80\x9a",
        131 => "\xc6\x92",
        132 => "\xe2\x80\x9e",
        133 => "\xe2\x80\xa6",
        134 => "\xe2\x80\xa0",
        135 => "\xe2\x80\xa1",
        136 => "\xcb\x86",
        137 => "\xe2\x80\xb0",
        138 => "\xc5\xa0",
        139 => "\xe2\x80\xb9",
        140 => "\xc5\x92",
        142 => "\xc5\xbd",
        145 => "\xe2\x80\x98",
        146 => "\xe2\x80\x99",
        147 => "\xe2\x80\x9c",
        148 => "\xe2\x80\x9d",
        149 => "\xe2\x80\xa2",
        150 => "\xe2\x80\x93",
        151 => "\xe2\x80\x94",
        152 => "\xcb\x9c",
        153 => "\xe2\x84\xa2",
        154 => "\xc5\xa1",
        155 => "\xe2\x80\xba",
        156 => "\xc5\x93",
        158 => "\xc5\xbe",
        159 => "\xc5\xb8"
    );
    protected static $brokenUtf8ToUtf8 = array(
        "\xc2\x80" => "\xe2\x82\xac",
        "\xc2\x82" => "\xe2\x80\x9a",
        "\xc2\x83" => "\xc6\x92",
        "\xc2\x84" => "\xe2\x80\x9e",
        "\xc2\x85" => "\xe2\x80\xa6",
        "\xc2\x86" => "\xe2\x80\xa0",
        "\xc2\x87" => "\xe2\x80\xa1",
        "\xc2\x88" => "\xcb\x86",
        "\xc2\x89" => "\xe2\x80\xb0",
        "\xc2\x8a" => "\xc5\xa0",
        "\xc2\x8b" => "\xe2\x80\xb9",
        "\xc2\x8c" => "\xc5\x92",
        "\xc2\x8e" => "\xc5\xbd",
        "\xc2\x91" => "\xe2\x80\x98",
        "\xc2\x92" => "\xe2\x80\x99",
        "\xc2\x93" => "\xe2\x80\x9c",
        "\xc2\x94" => "\xe2\x80\x9d",
        "\xc2\x95" => "\xe2\x80\xa2",
        "\xc2\x96" => "\xe2\x80\x93",
        "\xc2\x97" => "\xe2\x80\x94",
        "\xc2\x98" => "\xcb\x9c",
        "\xc2\x99" => "\xe2\x84\xa2",
        "\xc2\x9a" => "\xc5\xa1",
        "\xc2\x9b" => "\xe2\x80\xba",
        "\xc2\x9c" => "\xc5\x93",
        "\xc2\x9e" => "\xc5\xbe",
        "\xc2\x9f" => "\xc5\xb8"
    );
    protected static $utf8ToWin1252 = array(
        "\xe2\x82\xac" => "\x80",
        "\xe2\x80\x9a" => "\x82",
        "\xc6\x92" => "\x83",
        "\xe2\x80\x9e" => "\x84",
        "\xe2\x80\xa6" => "\x85",
        "\xe2\x80\xa0" => "\x86",
        "\xe2\x80\xa1" => "\x87",
        "\xcb\x86" => "\x88",
        "\xe2\x80\xb0" => "\x89",
        "\xc5\xa0" => "\x8a",
        "\xe2\x80\xb9" => "\x8b",
        "\xc5\x92" => "\x8c",
        "\xc5\xbd" => "\x8e",
        "\xe2\x80\x98" => "\x91",
        "\xe2\x80\x99" => "\x92",
        "\xe2\x80\x9c" => "\x93",
        "\xe2\x80\x9d" => "\x94",
        "\xe2\x80\xa2" => "\x95",
        "\xe2\x80\x93" => "\x96",
        "\xe2\x80\x94" => "\x97",
        "\xcb\x9c" => "\x98",
        "\xe2\x84\xa2" => "\x99",
        "\xc5\xa1" => "\x9a",
        "\xe2\x80\xba" => "\x9b",
        "\xc5\x93" => "\x9c",
        "\xc5\xbe" => "\x9e",
        "\xc5\xb8" => "\x9f"
    );

    static function toUTF8($text) {
        /**
         * Function Encoding::toUTF8
         *
         * This function leaves UTF8 characters alone, while converting almost all non-UTF8 to UTF8.
         * 
         * It assumes that the encoding of the original string is either Windows-1252 or ISO 8859-1.
         *
         * It may fail to convert characters to UTF-8 if they fall into one of these scenarios:
         *
         * 1) when any of these characters:   ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞß
         *    are followed by any of these:  ("group B")
         *                                    ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶•¸¹º»¼½¾¿
         * For example:   %ABREPRESENT%C9%BB. «REPRESENTÉ»
         * The "«" (%AB) character will be converted, but the "É" followed by "»" (%C9%BB) 
         * is also a valid unicode character, and will be left unchanged.
         *
         * 2) when any of these: àáâãäåæçèéêëìíîï  are followed by TWO chars from group B,
         * 3) when any of these: ðñòó  are followed by THREE chars from group B.
         *
         * @name toUTF8
         * @param string $text  Any string.
         * @return string  The same string, UTF8 encoded
         *
         */
        if (is_array($text)) {
            foreach ($text as $k => $v) {
                $text[$k] = self::toUTF8($v);
            }
            return $text;
        } elseif (is_string($text)) {

            $max = strlen($text);
            $buf = "";
            for ($i = 0; $i < $max; $i++) {
                $c1 = $text{$i};
                if ($c1 >= "\xc0") { //Should be converted to UTF8, if it's not UTF8 already
                    $c2 = $i + 1 >= $max ? "\x00" : $text{$i + 1};
                    $c3 = $i + 2 >= $max ? "\x00" : $text{$i + 2};
                    $c4 = $i + 3 >= $max ? "\x00" : $text{$i + 3};
                    if ($c1 >= "\xc0" & $c1 <= "\xdf") { //looks like 2 bytes UTF8
                        if ($c2 >= "\x80" && $c2 <= "\xbf") { //yeah, almost sure it's UTF8 already
                            $buf .= $c1 . $c2;
                            $i++;
                        } else { //not valid UTF8.  Convert it.
                            $cc1 = (chr(ord($c1) / 64) | "\xc0");
                            $cc2 = ($c1 & "\x3f") | "\x80";
                            $buf .= $cc1 . $cc2;
                        }
                    } elseif ($c1 >= "\xe0" & $c1 <= "\xef") { //looks like 3 bytes UTF8
                        if ($c2 >= "\x80" && $c2 <= "\xbf" && $c3 >= "\x80" && $c3 <= "\xbf") { //yeah, almost sure it's UTF8 already
                            $buf .= $c1 . $c2 . $c3;
                            $i = $i + 2;
                        } else { //not valid UTF8.  Convert it.
                            $cc1 = (chr(ord($c1) / 64) | "\xc0");
                            $cc2 = ($c1 & "\x3f") | "\x80";
                            $buf .= $cc1 . $cc2;
                        }
                    } elseif ($c1 >= "\xf0" & $c1 <= "\xf7") { //looks like 4 bytes UTF8
                        if ($c2 >= "\x80" && $c2 <= "\xbf" && $c3 >= "\x80" && $c3 <= "\xbf" && $c4 >= "\x80" && $c4 <= "\xbf") { //yeah, almost sure it's UTF8 already
                            $buf .= $c1 . $c2 . $c3;
                            $i = $i + 2;
                        } else { //not valid UTF8.  Convert it.
                            $cc1 = (chr(ord($c1) / 64) | "\xc0");
                            $cc2 = ($c1 & "\x3f") | "\x80";
                            $buf .= $cc1 . $cc2;
                        }
                    } else { //doesn't look like UTF8, but should be converted
                        $cc1 = (chr(ord($c1) / 64) | "\xc0");
                        $cc2 = (($c1 & "\x3f") | "\x80");
                        $buf .= $cc1 . $cc2;
                    }
                } elseif (($c1 & "\xc0") == "\x80") { // needs conversion
                    if (isset(self::$win1252ToUtf8[ord($c1)])) { //found in Windows-1252 special cases
                        $buf .= self::$win1252ToUtf8[ord($c1)];
                    } else {
                        $cc1 = (chr(ord($c1) / 64) | "\xc0");
                        $cc2 = (($c1 & "\x3f") | "\x80");
                        $buf .= $cc1 . $cc2;
                    }
                } else { // it doesn't need convesion
                    $buf .= $c1;
                }
            }
            return $buf;
        } else {
            return $text;
        }
    }

    static function toWin1252($text) {
        if (is_array($text)) {
            foreach ($text as $k => $v) {
                $text[$k] = self::toWin1252($v);
            }
            return $text;
        } elseif (is_string($text)) {
            return utf8_decode(str_replace(array_keys(self::$utf8ToWin1252), array_values(self::$utf8ToWin1252), self::toUTF8($text)));
        } else {
            return $text;
        }
    }

    static function toISO8859($text) {
        return self::toWin1252($text);
    }

    static function toLatin1($text) {
        return self::toWin1252($text);
    }

    static function fixUTF8($text) {
        if (is_array($text)) {
            foreach ($text as $k => $v) {
                $text[$k] = self::fixUTF8($v);
            }
            return $text;
        }

        $last = "";
        while ($last <> $text) {
            $last = $text;
            $text = self::toUTF8(utf8_decode(str_replace(array_keys(self::$utf8ToWin1252), array_values(self::$utf8ToWin1252), $text)));
        }
        $text = self::toUTF8(utf8_decode(str_replace(array_keys(self::$utf8ToWin1252), array_values(self::$utf8ToWin1252), $text)));
        return $text;
    }

    static function UTF8FixWin1252Chars($text) {
        // If you received an UTF-8 string that was converted from Windows-1252 as it was ISO8859-1 
        // (ignoring Windows-1252 chars from 80 to 9F) use this function to fix it.
        // See: http://en.wikipedia.org/wiki/Windows-1252

        return str_replace(array_keys(self::$brokenUtf8ToUtf8), array_values(self::$brokenUtf8ToUtf8), $text);
    }

    static function removeBOM($str = "") {
        if (substr($str, 0, 3) == pack("CCC", 0xef, 0xbb, 0xbf)) {
            $str = substr($str, 3);
        }
        return $str;
    }

    public static function normalizeEncoding($encodingLabel) {
        $encoding = strtoupper($encodingLabel);
        $enc = preg_replace('/[^a-zA-Z0-9\s]/', '', $encoding);
        $equivalences = array(
            'ISO88591' => 'ISO-8859-1',
            'ISO8859' => 'ISO-8859-1',
            'ISO' => 'ISO-8859-1',
            'LATIN1' => 'ISO-8859-1',
            'LATIN' => 'ISO-8859-1',
            'UTF8' => 'UTF-8',
            'UTF' => 'UTF-8',
            'WIN1252' => 'ISO-8859-1',
            'WINDOWS1252' => 'ISO-8859-1'
        );

        if (empty($equivalences[$encoding])) {
            return 'UTF-8';
        }

        return $equivalences[$encoding];
    }

    public static function encode($encodingLabel, $text) {
        $encodingLabel = self::normalizeEncoding($encodingLabel);
        if ($encodingLabel == 'UTF-8')
            return Encoding::toUTF8($text);
        if ($encodingLabel == 'ISO-8859-1')
            return Encoding::toLatin1($text);
    }

}

?>